package com.xinyue.cross.server.client;

import com.alibaba.cloud.nacos.discovery.NacosDiscoveryClient;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.event.InstancesChangeEvent;
import com.alibaba.nacos.common.notify.Event;
import com.alibaba.nacos.common.notify.NotifyCenter;
import com.alibaba.nacos.common.notify.listener.Subscriber;
import com.xinyue.cross.server.client.model.GameServerMetaData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 游戏服务发现客户端，主要是负责从nacos中获取已注册的业务服务，并创建与这些服务的长连接
 *
 * @author 王广帅
 * @since 2023/8/10 21:12
 **/

public class GameServerDiscoveryClient {

    private Logger logger = LoggerFactory.getLogger(GameServerDiscoveryClient.class);
    @Autowired
    private NacosDiscoveryClient discoveryClient;
    @Autowired
    private GameServerConnectionService gameServerConnectionService;
    /**
     * 存储获取到注册的业务服务元数据，就是服务的基本描述信息
     */
    private Map<String, List<GameServerMetaData>> gameServerMetaDataMap = new HashMap<>(3);

    @PostConstruct
    public void init() {
        this.initGameServer();
        this.addInstanceChangeListener();
    }

    private void initGameServer() {
        this.gameServerMetaDataMap = this.findGameServer();
        logger.info("刷新服务列表结果：{}", JSON.toJSONString(gameServerMetaDataMap));
        gameServerConnectionService.createConnectionClient(this.gameServerMetaDataMap);
    }

    private Map<String, List<GameServerMetaData>> findGameServer() {
        List<String> services = discoveryClient.getServices();
        Map<String, List<GameServerMetaData>> resultMap = new HashMap<>(3);
        for (String serviceId : services) {
            List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
            List<GameServerMetaData> gameServerMetaDataList = new ArrayList<>();
            for (ServiceInstance instance : instances) {
                GameServerMetaData gameServerMetaData = new GameServerMetaData();
                gameServerMetaData.setHost(instance.getHost());
                gameServerMetaData.setWebPort(instance.getPort());
                if (instance.getMetadata() != null) {
                    String socketPortValue = instance.getMetadata().get("socketPort");
                    if (socketPortValue != null) {
                        gameServerMetaData.setSocketPort(Integer.parseInt(socketPortValue));
                    }
                    String instanceName = instance.getMetadata().get("instanceName");
                    gameServerMetaData.setInstanceName(instanceName);
                }
                gameServerMetaDataList.add(gameServerMetaData);
            }
            resultMap.put(serviceId, gameServerMetaDataList);
        }
        return resultMap;
    }

    public void addInstanceChangeListener() {
        NotifyCenter.registerSubscriber(new Subscriber() {
            @Override
            public void onEvent(Event event) {
                if (event instanceof InstancesChangeEvent) {
                    logger.info("服务实例发生变化，重新刷新服务");
                    initGameServer();
                } else {
                    logger.info("收到nacos client事件，eventName: {}", event.getClass().getName());
                }
            }

            @Override
            public Class<? extends Event> subscribeType() {
                return InstancesChangeEvent.class;
            }
        });
    }
}
